#include "interconversion.h"

#include <QFormLayout>
#include <QBoxLayout>
#include <QLabel>
#include <QRegExpValidator>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QGroupBox>

InterConversion::InterConversion(QWidget *parent):
    QWidget(parent)
{
    initUi();
    initConnect();
    setEditValidator();
}

InterConversion::~InterConversion()
{

}


void InterConversion::initUi()
{
    //整形数转换界面
    m_binary = new DLineEdit();
    m_octal = new DLineEdit();
    m_decimal = new DLineEdit();
    m_hexadecimal = new DLineEdit();

//    m_binary->setClearButtonEnabled(true);
//    m_octal->setClearButtonEnabled(true);
//    m_decimal->setClearButtonEnabled(true);
//    m_hexadecimal->setClearButtonEnabled(true);

    QGroupBox *intGroup = new QGroupBox(this);
    intGroup->setTitle("整形数转换");
    intGroup->setGeometry(20, 20, 410, 300);

    QGridLayout *intLayout = new QGridLayout();
    QLabel *lbBinary = new QLabel("二进制:");
    QLabel *lbOctal = new QLabel("八进制:");
    QLabel *lbDecimal = new QLabel("十进制:");
    QLabel *lbHexAdecimal = new QLabel("十六进制:");

    intLayout->addWidget(lbBinary, 0, 0);
    intLayout->addWidget(m_binary, 0, 1);
    intLayout->addWidget(lbOctal, 1, 0);
    intLayout->addWidget(m_octal, 1, 1);
    intLayout->addWidget(lbDecimal, 2, 0);
    intLayout->addWidget(m_decimal, 2, 1);
    intLayout->addWidget(lbHexAdecimal, 3, 0);
    intLayout->addWidget(m_hexadecimal, 3, 1);

    intGroup->setLayout(intLayout);
}

void InterConversion::initConnect()
{
    connect(m_binary, SIGNAL(textChanged(const QString)), this, SLOT(slotBinaryToDeciaml(const QString)));      //2->10
    connect(m_octal, SIGNAL(textChanged(const QString)), this, SLOT(slotOctalToDeciaml(const QString)));        //8->10
    connect(m_hexadecimal, SIGNAL(textChanged(const QString)), this, SLOT(slotHexToDeciaml(const QString)));    //16->10
    connect(m_decimal, SIGNAL(textChanged(const QString)), this, SLOT(slotDeciamlToBinary(const QString)));     //10->2
    connect(m_decimal, SIGNAL(textChanged(const QString)), this, SLOT(slotDeciamlToOctal(const QString)));      //10->8
    connect(m_decimal, SIGNAL(textChanged(const QString)), this, SLOT(slotDeciamlToHex(const QString)));        //10->16
}

void InterConversion::setEditValidator()
{
    // 二进制
    QRegExp rxBinary("[01]*");
    QRegExpValidator *rvBinary = new QRegExpValidator(rxBinary, this);
    m_binary->lineEdit()->setValidator(rvBinary);

    // 八进制
    QRegExp rxOctal("[0-7]*");
    QRegExpValidator *rvOctal = new QRegExpValidator(rxOctal, this);
    m_octal->lineEdit()->setValidator(rvOctal);

    // 十进制
    QRegExp rxDecimal("[0-9]*");
    QRegExpValidator *rvDecimal = new QRegExpValidator(rxDecimal, this);
    m_decimal->lineEdit()->setValidator(rvDecimal);

    // 十六进制
    QRegExp rxHex("[0-9A-Fa-f]*");
    QRegExpValidator *rvHex = new QRegExpValidator(rxHex, this);
    m_hexadecimal->lineEdit()->setValidator(rvHex);
}

// 二进制转十进制
void InterConversion::slotBinaryToDeciaml(const QString &str)
{
    unsigned int j = 1, value = 0;
    for(int i=str.length()-1; i>=0; i--)
    {
        value += str.mid(i,1).toUInt()*j;
        j *= 2;
    }

    m_decimal->setText(QString::number(value));
}

// 八进制转十进制
void InterConversion::slotOctalToDeciaml(const QString &str)
{
    unsigned int j = 1, value = 0;
    for(int i=str.length()-1; i>=0; i--)
    {
        value += str.mid(i,1).toUInt()*j;
        j *= 8;
    }

    m_decimal->setText(QString::number(value));
}

// 十六进制转十进制
void InterConversion::slotHexToDeciaml(const QString &str)
{
    bool ok;
    unsigned int dec = str.toUInt(&ok, 16);
    m_decimal->setText(QString::number(dec));
}

//十进制转二进制
void InterConversion::slotDeciamlToBinary(const QString &str)
{
    unsigned int n = str.toUInt();
    long b,k,i;
    long remainder[50] = {0};
    k=0;
    while(n != 0)
    {
        b = n / 2;
        remainder[k]= n - b * 2;
        k++;
        n = n / 2;
    }

    QString str1;
    for (i = k-1; i>=0; i--)
    {
        str1 += QString::number(remainder[i]);
    }

    m_binary->setText(str1);
}

// 十进制转八进制
void InterConversion::slotDeciamlToOctal(const QString &str)
{
    unsigned int n = str.toUInt();
    long b,k,i;
    long remainder[50] = {0};
    k=0;
    while(n != 0)
    {
        b = n / 8;
        remainder[k]= n - b * 8;
        k++;
        n = n / 8;
    }

    QString str1;
    for (i = k-1; i>=0; i--)
    {
        str1 += QString::number(remainder[i]);
    }

    m_octal->setText(str1);
}

//十进制转十六进制
void InterConversion::slotDeciamlToHex(const QString &str)
{
    unsigned int n = str.toUInt();
    QString result = QString::number( n, 16 );
    m_hexadecimal->setText(result);
    if (m_binary->text() == "")
    {
        m_hexadecimal->setText("");
    }
}
